package com.mgy.example.service.common.lock.aop;

import com.mgy.example.annotation.MySqlLock;
import com.mgy.example.dao.mapper.lock.ILockDao;
import com.mgy.example.domain.lock.Lock;
import com.mgy.example.utils.LockUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
@Aspect
@Component
public class MySqlLockAspect {
    @Autowired
    private ILockDao lockDao;

    @Pointcut("@annotation(com.mgy.example.annotation.MySqlLock)")
    public void distributedLockPointcut() {

    }

    @Around(value = "distributedLockPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        MySqlLock mySqlLock = methodSignature.getMethod().getAnnotation(MySqlLock.class);
        String[] parameterNames = methodSignature.getParameterNames();
        Class[] parameterTypes = methodSignature.getMethod().getParameterTypes();
        Object[] parameterValues = joinPoint.getArgs();
        //获取锁的名称
        String lockName = LockUtil.getLockName(mySqlLock.lockName(), mySqlLock.fieldName(), parameterNames, parameterTypes, parameterValues);
        Lock lock = new Lock();
        lock.setKey(lockName);
        lock.setNum(0);
        lock.setCreated(new Date());
        lock.setModified(new Date());
        try {
            //加锁
            lockDao.lock(lock);
            //执行业务方法
            return joinPoint.proceed();
        } finally {
            //解锁
            lockDao.unlock(lock);
        }
    }

}
